package com.xhs.service;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xhs.dto.XhsSearchResponse;
import com.xhs.model.QrCodeResult;
import com.xhs.model.SearchTask;
import com.xhs.manager.SearchTaskManager;
import com.xhs.util.PostTimeUtil;
import com.xhs.util.TimeFormatUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 定时任务执行服务
 *
 * @author xhs
 */
@Slf4j
@Service
public class TaskSchedulerService {

    @Autowired
    private TaskService taskService;

    @Autowired
    private SearchNotesService searchNotesService;

    @Autowired
    private QrCodeDetectionService qrCodeDetectionService;

    @Autowired
    private SearchTaskManager searchTaskManager;

    /**
     * 定时扫描需要执行的任务（每分钟执行一次）
     */
    @Scheduled(fixedDelay = 60000)
    public void executeScheduledTasks() {
        List<SearchTask> enabledTasks = searchTaskManager.findEnabledTasks();

        if (enabledTasks.isEmpty()) {
            log.debug("没有启用的任务");
            return;
        }

        log.debug("扫描到{}个启用的任务", enabledTasks.size());

        LocalDateTime now = LocalDateTime.now();
        for (SearchTask task : enabledTasks) {
            try {
                // 检查任务是否需要执行
                if (shouldExecuteTask(task, now)) {
                    log.info("任务需要执行: id={}, taskName={}", task.getId(), task.getTaskName());
                    executeTask(task);
                    // 更新最后执行时间
                    searchTaskManager.updateLastExecuteTime(task.getId(), now);
                }
            } catch (Exception e) {
                log.error("执行任务失败: id={}", task.getId(), e);
                searchTaskManager.updateTaskError(task.getId(), e.getMessage());
            }
        }
    }

    /**
     * 判断任务是否需要执行
     */
    private boolean shouldExecuteTask(SearchTask task, LocalDateTime now) {
        // 如果任务正在执行，不重复执行
        if ("RUNNING".equals(task.getStatus())) {
            return false;
        }

        // 获取任务的执行间隔（分钟）
        Integer executeInterval = task.getExecuteInterval();
        if (executeInterval == null || executeInterval <= 0) {
            executeInterval = 10; // 默认10分钟
        }

        // 如果从未执行过，需要执行
        if (task.getLastExecuteTime() == null) {
            return true;
        }

        // 计算距离上次执行的时间
        LocalDateTime lastExecuteTime = task.getLastExecuteTime();
        LocalDateTime nextExecuteTime = lastExecuteTime.plusMinutes(executeInterval);

        // 如果当前时间超过了下次执行时间，需要执行
        return now.isAfter(nextExecuteTime) || now.isEqual(nextExecuteTime);
    }

    /**
     * 立即执行任务
     *
     * @param task 任务
     */
    public void executeTaskImmediately(SearchTask task) {
        executeTask(task);
    }

    /**
     * 执行单个任务
     */
    private void executeTask(SearchTask task) {
        log.info("开始执行任务: id={}, taskName={}", task.getId(), task.getTaskName());

        // 更新任务状态为执行中
        taskService.updateTaskStatus(task.getId(), "RUNNING");

        // 将关键词从JSON字符串解析为数组
        List<String> allKeywords = splitKeywordsByChineseComma(task.getKeywords());
        int totalQrCodes = 0;

        // 遍历所有关键词进行搜索
        for (int keywordIndex = 0; keywordIndex < allKeywords.size(); keywordIndex++) {
            String currentKeyword = allKeywords.get(keywordIndex);
            log.info("执行任务关键词: id={}, keyword=[{}], 进度:{}/{}",
                    task.getId(), currentKeyword, keywordIndex + 1, allKeywords.size());

            // 获取任务配置的搜索页数，默认为1页
            Integer searchPages = task.getSearchPages();
            if (searchPages == null || searchPages <= 0) {
                searchPages = 1;
            }

            // 根据配置的页数进行多页搜索
            for (int currentPage = 1; currentPage <= searchPages; currentPage++) {
                log.info("搜索关键词[{}]第{}页，总共{}页", currentKeyword, currentPage, searchPages);

                // 搜索笔记
                String responseJson = searchNotesService.searchNotesForTask(task.getPhoneNumber(), currentKeyword, currentPage);
                log.info("小红书搜索结果:{}", responseJson);

                // 处理搜索结果
                JSONObject responseObj = JSONUtil.parseObj(responseJson);
                int newQrCodes = processSearchResults(responseObj, task, currentKeyword);
                totalQrCodes += newQrCodes;

                log.info("关键词[{}]搜索第{}页完成，新增二维码{}个", currentKeyword, currentPage, newQrCodes);
            }
        }

        // 更新任务总的二维码数量
        searchTaskManager.updateTaskProgress(task.getId(), totalQrCodes);

        // 标记任务完成
        taskService.updateTaskStatus(task.getId(), "COMPLETED");
        log.info("任务执行完成: id={}, 总共处理了{}个关键词，扫描到{}个二维码",
                task.getId(), allKeywords.size(), totalQrCodes);
    }

    /**
     * 将关键词字符串分割成数组
     */
    private List<String> splitKeywordsByChineseComma(String keywordsStr) {
        List<String> keywords = new ArrayList<>();
        if (keywordsStr != null && !keywordsStr.trim().isEmpty()) {
            // 兼容性处理：检查是否为旧的JSON格式
            if (keywordsStr.startsWith("[") && keywordsStr.endsWith("]")) {
                try {
                    JSONArray jsonArray = JSONUtil.parseArray(keywordsStr);
                    for (Object obj : jsonArray) {
                        if (obj != null) {
                            keywords.add(obj.toString().trim());
                        }
                    }
                    return keywords;
                } catch (Exception e) {
                    log.warn("解析关键词JSON失败，使用逗号分割: {}", keywordsStr);
                }
            }
            
            // 新格式：直接使用逗号分割
            String[] keywordArray = keywordsStr.split("[，,]");
            for (String keyword : keywordArray) {
                if (keyword != null && !keyword.trim().isEmpty()) {
                    keywords.add(keyword.trim());
                }
            }
        }
        return keywords;
    }

    /**
     * 处理搜索结果
     */
    private int processSearchResults(JSONObject responseJson, SearchTask task, String keyword) {
        int newQrCodes = 0;

        // 使用HuTool直接转换为Java Bean
        XhsSearchResponse searchResponse = JSONUtil.toBean(responseJson, XhsSearchResponse.class);
        if (searchResponse == null || searchResponse.getData() == null) {
            log.warn("解析搜索结果失败: id={}, keyword={}", task.getId(), keyword);
            return 0;
        }

        List<XhsSearchResponse.ItemInfo> items = searchResponse.getData().getItems();
        if (items == null || items.isEmpty()) {
            log.info("没有找到搜索结果: id={}, keyword={}", task.getId(), keyword);
            return 0;
        }

        // 遍历搜索结果
        for (XhsSearchResponse.ItemInfo item : items) {
            String noteId = item.getId();
            XhsSearchResponse.NoteCard noteCard = item.getNote_card();

            if (noteCard == null) {
                continue;
            }

            // 检查帖子发布时间是否超过限制，并获取帖子创建时间
            boolean timeExceeded = false;
            String postCreateTime = null;
            List<XhsSearchResponse.CornerTagInfo> cornerTagInfoList = noteCard.getCorner_tag_info();
            if (cornerTagInfoList != null && !cornerTagInfoList.isEmpty()) {
                for (XhsSearchResponse.CornerTagInfo cornerTagInfo : cornerTagInfoList) {
                    if ("publish_time".equals(cornerTagInfo.getType())) {
                        String timeText = cornerTagInfo.getText();
                        // 将时间文本转换为中文格式
                        postCreateTime = TimeFormatUtil.formatXhsTimeToChinese(timeText);
                        if (PostTimeUtil.isPostTimeExceeded(timeText, task.getPostTimeLimit())) {
                            timeExceeded = true;
                            log.debug("帖子时间超过限制，跳过: noteId={}, timeText={}, limit={}天", 
                                    noteId, timeText, task.getPostTimeLimit());
                            break;
                        }
                    }
                }
            }

            // 如果帖子时间超过限制，跳过此帖子
            if (timeExceeded) {
                continue;
            }

            String displayTitle = noteCard.getDisplay_title();
            if (displayTitle == null) {
                displayTitle = "";
            }

            List<XhsSearchResponse.ImageInfo> imageList = noteCard.getImage_list();
            if (imageList != null && !imageList.isEmpty()) {
                for (XhsSearchResponse.ImageInfo imageInfo : imageList) {
                    List<XhsSearchResponse.ImageDetailInfo> infoList = imageInfo.getInfo_list();

                    if (infoList != null && !infoList.isEmpty()) {
                        // 取第一个图片信息
                        XhsSearchResponse.ImageDetailInfo imageDetail = infoList.get(0);
                        String imageUrl = imageDetail.getUrl();

                        if (imageUrl != null && !imageUrl.isEmpty()) {
                            // 检测图片中是否包含二维码
                            if (qrCodeDetectionService.isWechatQrCode(imageUrl)) {
                                // 创建二维码结果
                                QrCodeResult result = new QrCodeResult();
                                result.setQrCodeUrl(imageUrl); // 使用图片URL作为二维码URL
                                result.setImageUrl(imageUrl);
                                result.setNoteTitle(displayTitle);
                                result.setNoteId(noteId);
                                result.setKeyword(keyword);
                                result.setPostCreateTime(postCreateTime); // 设置帖子创建时间
                                LocalDateTime scanTime = LocalDateTime.now();
                                result.setScanTime(scanTime);
                                result.setScanTimeFormatted(TimeFormatUtil.formatToChinese(scanTime)); // 设置格式化的扫描时间

                                // 保存到MySQL
                                taskService.saveQrCodeResult(task.getId(), result);
                                newQrCodes++;

                                log.info("发现二维码: id={}, keyword={}, title={}, url={}",
                                        task.getId(), keyword, displayTitle, imageUrl);
                            }
                        }
                    }
                }
            }
        }

        return newQrCodes;
    }
} 